#prima regularni izraz iz kojeg gradi e-NKA automat i zapisuje ga u datoteku
class generator_automata:

    broj_stanja=0       #picku materinu
    e_prijelazi=[]
    prijelazi=[]


    def __init__(self):
        self.broj_stanja=0
        self.e_prijelazi=[]
        self.prijelazi=[]

    def reset(self):
        self.broj_stanja=0
        self.e_prijelazi=[]
        self.prijelazi=[]

    def pisi_u_datoteku(self,datoteka):

        #datoteka=open(ime,"w")
        datoteka.write("0")
        for i in range(1,self.broj_stanja):

            datoteka.write(',{}'.format(i))
        datoteka.write("\n")
        
        for i in range(len(self.prijelazi[0][2])):
            if self.prijelazi[0][2][i] == '\n':
                datoteka.write('\\n')
            elif self.prijelazi[0][2][i] == ' ':
                datoteka.write('\\_')
            elif self.prijelazi[0][2][i] == '\t':
                datoteka.write('\\t')
            else :
                datoteka.write(self.prijelazi[0][2])
        
            
        for i in range(1,len(self.prijelazi)-1):
            datoteka.write(",")
            for j in range(len(self.prijelazi[i][2])):
                if self.prijelazi[i][2][j] == '\n':
                    datoteka.write('\\n')
                elif self.prijelazi[i][2][j] == ' ':
                    datoteka.write('\\_')
                elif self.prijelazi[i][2][j] == '\t':
                    datoteka.write('\\t')
                else :
                    datoteka.write(self.prijelazi[i][2])
        datoteka.write("\n")
        for i in range(0,len(self.prijelazi)):
                datoteka.write('{}'.format(self.prijelazi[i][0]))
                datoteka.write(",")
                if self.prijelazi[i][2] != '\n':
                    for j in range(len(self.prijelazi[i][2].strip('\n'))):
                        if self.prijelazi[i][2][j] == '\n':
                            datoteka.write('\\n')
                            print('trala')
                        elif self.prijelazi[i][2][j] == ' ':
                            datoteka.write('\\_')
                            print('blablabla')
                        elif self.prijelazi[i][2][j] == '\t':
                            datoteka.write('\\t')
                        else :
                            datoteka.write(self.prijelazi[i][2])
                else:
                    datoteka.write('\\n')
                datoteka.write("->")
                datoteka.write('{}'.format(self.prijelazi[i][1]))
                datoteka.write("\n")

        for i in range(0,len(self.e_prijelazi)):
                datoteka.write('{}'.format(self.e_prijelazi[i][0]))
                datoteka.write(",")
                datoteka.write("$")
                datoteka.write("->")
                datoteka.write('{}'.format(self.e_prijelazi[i][1]))
                datoteka.write("\n")
        datoteka.write("---\n")


    def novo_stanje(self):
            self.broj_stanja=self.broj_stanja+1
            return self.broj_stanja-1







    def je_operator(self,izraz,i):
         br = 0
         while (i-1>=0 and izraz[i-1]=='\\'):
            br = br + 1
            i = i - 1

         if br%2==0:
            return 1
         else:
            return 0








    def dodaj_epsilon_prijelaz(self,lijevo,privremeno_lijevo):
        self.e_prijelazi.append([lijevo,privremeno_lijevo])





    def dodaj_prijelaz(self, trenutno_stanje, sljedece_stanje,prijelazni_znak):
        self.prijelazi.append([trenutno_stanje,sljedece_stanje,prijelazni_znak])
        return 0







    def pretvori(self,izraz):

        izbori=[]
        br_zagrada = 0
        j=0
        for i in range(0,len(izraz),1):
            if izraz[i]=='(' and self.je_operator(izraz, i):
                br_zagrada = br_zagrada + 1
            elif izraz[i]==')' and self.je_operator(izraz, i):
                br_zagrada = br_zagrada - 1
            elif br_zagrada==0 and izraz[i]=='|' and self.je_operator(izraz, i):
                izbori.append(izraz[j:i])
                j=i+1


        if j!=0:
            izbori.append(izraz[j:])


        lijevo_stanje = self.novo_stanje()
        desno_stanje = self.novo_stanje()

        if j!=0:
            for i in range (len(izbori)):
                privremeno=self.pretvori(izbori[i])
                self.dodaj_epsilon_prijelaz( lijevo_stanje, privremeno[0])
                self.dodaj_epsilon_prijelaz( privremeno[1], desno_stanje)

        else:
                 prefiksirano = 0
                 trenutno_stanje = lijevo_stanje
                 i=0
                 while(i<len(izraz)):
                    if prefiksirano!=0:

                        prefiksirano = 0

                        if izraz[i] == 't':
                            prijelazni_znak = '\t'
                        elif izraz[i] == '$':
                            prijelazni_znak = '\$'
                        elif izraz[i] == 'n':
                            prijelazni_znak = '\n'
                        elif izraz[i] == '_':
                            prijelazni_znak = ' '
                        else:
                            prijelazni_znak = izraz[i]

                        sljedece_stanje = self.novo_stanje()
                        self.dodaj_prijelaz(trenutno_stanje, sljedece_stanje,prijelazni_znak)

                        if i+1<len(izraz) and izraz[i+1]=='*':
                            dodaj_epsilon_prijelaz( trenutno_stanje, sljedece_stanje)
                            dodaj_epsilon_prijelaz( sljedece_stanje, trenutno_stanje)
                            i = i+1


                        trenutno_stanje = sljedece_stanje




                    else:
                        if izraz[i] == '\\':
                            prefiksirano = 1
                            i=i+1
                            continue

                        if izraz[i] != '(':

                            sljedece_stanje = self.novo_stanje()
                            if izraz[i] == '$':
                                self.dodaj_epsilon_prijelaz( trenutno_stanje, sljedece_stanje)
                            else:
                                self.dodaj_prijelaz( trenutno_stanje, sljedece_stanje, izraz[i])

                            if i+1<len(izraz) and izraz[i+1]=='*':
                                self.dodaj_epsilon_prijelaz( trenutno_stanje, sljedece_stanje)
                                self.dodaj_epsilon_prijelaz( sljedece_stanje, trenutno_stanje)
                                i = i+1

                            trenutno_stanje = sljedece_stanje

                        else:

                            br_zagrada=0
                            for k in range(i,len(izraz),1):
                                if izraz[k]=='(' and self.je_operator(izraz, k):
                                    br_zagrada = br_zagrada + 1
                                elif izraz[k]==')' and self.je_operator(izraz, k):
                                        br_zagrada = br_zagrada - 1
                                        if br_zagrada==0  and self.je_operator(izraz, k):
                                            j=k
                                            break

                            privremeno = self.pretvori(izraz[i+1:j])
                            self.dodaj_epsilon_prijelaz( trenutno_stanje,privremeno[0])
                            i = j
                            trenutno_stanje = privremeno[1]
                            if i+1<len(izraz) and izraz[i+1]=='*':
                                self.dodaj_epsilon_prijelaz(privremeno[0], privremeno[1])
                                self.dodaj_epsilon_prijelaz( privremeno[1], privremeno[0])
                                i = i+1

                    i=i+1
                 self.dodaj_epsilon_prijelaz(trenutno_stanje, desno_stanje)
        povratna_vrijednost=[]
        povratna_vrijednost.append(lijevo_stanje)
        povratna_vrijednost.append(desno_stanje)
        return povratna_vrijednost


def main():

        a=generator_automata()
        b=open("test.txt","r")

        for temp in b:
            #temp=b.readline()
            if temp[len(temp)-1]=="\n":
                temp=temp[0:len(temp)-1]
            #print(temp)
            a.reset()
            izlaz=a.pretvori(temp)
            #print(izlaz)
            #print(a.prijelazi)
            #print(a.e_prijelazi)
            #print(a.broj_stanja)
            a.pisi_u_datoteku("def_automata.txt")



if __name__ == '__main__':
    main()

